#    pythonequations is a collection of equations expressed as Python classes
#    Copyright (C) 2011 James R. Phillips
#    2548 Vera Cruz Drive
#    Birmingham, AL 35235 USA
#    email: zunzun@zunzun.com
#
#    License: BSD-style (see LICENSE.txt in main source directory)
#    Version info: $Id: Trigonometric.py 328 2011-09-24 18:42:58Z zunzun.com $

import pythonequations, pythonequations.EquationBaseClasses, pythonequations.ExtraCodeForEquationBaseClasses
import numpy
numpy.seterr(all = 'raise') # numpy raises warnings, convert to exceptions to trap them


class RezaCustomOne3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Reza's Custom Equation One [radians]"
    _HTML = "z = (cos(a*x - b*y) + sin(c*x - d*y))<sup>n</sup> - (cos(f*x - g*y) + sin(h*x- i*y))<sup>n</sup>"
    coefficientDesignatorTuple = ('a', 'b', 'c', 'd', 'f', 'g', 'h', 'i', 'n')
    function_cpp_code = 'temp = pow(cos(coeff[0] * _id[_cwo[0]+i] - coeff[1] * _id[_cwo[1]+i]) + sin(coeff[2] * _id[_cwo[0]+i] - coeff[3] * _id[_cwo[1]+i]), coeff[8]);'
    function_cpp_code += 'temp -= pow(cos(coeff[4] * _id[_cwo[0]+i] - coeff[5] * _id[_cwo[1]+i]) + sin(coeff[6] * _id[_cwo[0]+i] - coeff[7] * _id[_cwo[1]+i]), coeff[8]);'


    def Initialize(self):
        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        try:
            nobs = len(self.IndependentDataArray[0])

            maxVal = max(self.IndependentDataArray[0])
            minVal = min(self.IndependentDataArray[0])
            self.upperCoefficientBoundsArray[0] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[0] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.upperCoefficientBoundsArray[2] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[2] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.upperCoefficientBoundsArray[4] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[4] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.upperCoefficientBoundsArray[6] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[6] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            
            maxVal = max(self.IndependentDataArray[1])
            minVal = min(self.IndependentDataArray[1])
            self.upperCoefficientBoundsArray[1] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[1] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.upperCoefficientBoundsArray[3] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[3] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.upperCoefficientBoundsArray[5] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[5] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.upperCoefficientBoundsArray[7] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[7] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
        except:
            pass

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = pow(cos(a*x_in - b*y_in) + sin(c*x_in - d*y_in), n);\n"
        s += "\ttemp -= pow(cos(f*x_in - g*y_in) + sin(h*x_in - i*y_in), n);\n"
        return s



class RezaCustomTwo3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Reza's Custom Equation Two [radians]"
    _HTML = "z = abs(cos((A*(x+B)) + C*(y+D))) + abs(cos((A*(x+B)) - C*(y+D))) - (sin(E*x+F))<sup>2</sup> - (sin(E*y+G))<sup>2</sup>"
    coefficientDesignatorTuple = ('A', 'B', 'C', 'D', 'E', 'F', 'G')
    function_cpp_code = 'temp_x_sq = coeff[0] * (coeff[1] + _id[_cwo[0]+i]);'
    function_cpp_code += 'temp_y_sq = coeff[2] * (coeff[3] + _id[_cwo[1]+i]);'
    function_cpp_code += 'temp = abs(cos(temp_x_sq + temp_y_sq)) + abs(cos(temp_x_sq - temp_y_sq));'
    function_cpp_code += 'temp -= pow(sin(coeff[4] * _id[_cwo[0]+i] + coeff[5]), 2.0);'
    function_cpp_code += 'temp -= pow(sin(coeff[4] * _id[_cwo[1]+i] + coeff[6]), 2.0);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = abs(cos((A*(x_in+B)) + C*(y_in+D))) + abs(cos((A*(x_in+B)) - C*(y_in+D))) - pow(sin(E*x_in+F), 2.0) - pow(sin(E*y_in+G), 2.0);\n"
        return s



class SineXY3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Sine XY [radians]"
    _HTML = "z = a * sin(xy)"
    coefficientDesignatorTuple = ('a')
    LinearSSQSolverFlag = 1
    function_cpp_code = 'temp = coeff[0] * _id[_cwo[0]+i];'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_SinXY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * sin(x_in * y_in);\n"
        return s



class SineXYTransform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Sine XY [radians] Transform"
    _HTML = "z = a * sin(b * xy + c)"
    coefficientDesignatorTuple = ('a', 'b', 'c')
    function_cpp_code = 'temp = coeff[0] * sin(coeff[1] * _id[_cwo[0]+i] + coeff[2]);'


    def Initialize(self):
        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        try:
            nobs = len(self.IndependentDataArray[0])
            maxVal = max(self.IndependentDataArray[0]) * max(self.IndependentDataArray[1])
            minVal = min(self.IndependentDataArray[0]) * min(self.IndependentDataArray[1])
            self.upperCoefficientBoundsArray[1] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[1] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
        except:
            pass

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_XY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * sin(b * x_in * y_in + c);\n"
        return s



class CoshXY3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Cosh XY [radians]"
    _HTML = "z = a * cosh(xy)"
    coefficientDesignatorTuple = ('a')
    LinearSSQSolverFlag = 1
    function_cpp_code = 'temp = coeff[0] * _id[_cwo[0]+i];'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_CoshXY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * cosh(x_in * y_in);\n"
        return s



class CoshXYTransform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Cosh XY [radians] Transform"
    _HTML = "z = a * cosh(b * xy + c)"
    coefficientDesignatorTuple = ('a', 'b', 'c')
    function_cpp_code = 'temp = coeff[0] * cosh(coeff[1] * _id[_cwo[0]+i] + coeff[2]);'


    def Initialize(self):
        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        try:
            nobs = len(self.IndependentDataArray[0])
            maxVal = max(self.IndependentDataArray[0]) * max(self.IndependentDataArray[1])
            minVal = min(self.IndependentDataArray[0]) * min(self.IndependentDataArray[1])
            self.upperCoefficientBoundsArray[1] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[1] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
        except:
            pass

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_XY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * cosh(b * x_in * y_in + c);\n"
        return s



class TanXY3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Tan XY [radians]"
    _HTML = "z = a * tan(xy)"
    coefficientDesignatorTuple = ('a')
    LinearSSQSolverFlag = 1
    function_cpp_code = 'temp = coeff[0] * _id[_cwo[0]+i];'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_TanXY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * tan(x_in * y_in);\n"
        return s



class TanXYTransform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Tan XY [radians] Transform"
    _HTML = "z = a * tan(b * xy + c)"
    coefficientDesignatorTuple = ('a', 'b', 'c')
    function_cpp_code = 'temp = coeff[0] * tan(coeff[1] * _id[_cwo[0]+i] + coeff[2]);'


    def Initialize(self):
        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        try:
            nobs = len(self.IndependentDataArray[0])
            maxVal = max(self.IndependentDataArray[0]) * max(self.IndependentDataArray[1])
            minVal = min(self.IndependentDataArray[0]) * min(self.IndependentDataArray[1])
            self.upperCoefficientBoundsArray[1] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[1] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
        except:
            pass

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_XY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * tan(b * x_in * y_in + c);\n"
        return s



class SineA3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Sine A [radians]"
    _HTML = "z = (a * sin(x)) + (b * sin(y))"
    coefficientDesignatorTuple = ('a', 'b')
    LinearSSQSolverFlag = 1
    function_cpp_code = 'temp = (coeff[0] * _id[_cwo[0]+i]) + (coeff[1] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_SinX(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_SinY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * sin(x_in)) + (b * sin(y_in));\n"
        return s



class SineA_Transform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Sine A [radians] Transform"
    _HTML = "z = (a * sin(bx+c)) + (d * sin(fy+g))"
    coefficientDesignatorTuple = ('a', 'b', 'c', 'd', 'f', 'g')
    function_cpp_code = 'temp = (coeff[0] * sin(coeff[1] * _id[_cwo[0]+i] + coeff[2])) + (coeff[3] * sin(coeff[4] * _id[_cwo[1]+i] + coeff[5]));'


    def Initialize(self):
        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        try:
            nobs = len(self.IndependentDataArray[0])

            maxVal = max(self.IndependentDataArray[0])
            minVal = min(self.IndependentDataArray[0])
            self.upperCoefficientBoundsArray[1] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[1] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            
            maxVal = max(self.IndependentDataArray[1])
            minVal = min(self.IndependentDataArray[1])
            self.upperCoefficientBoundsArray[4] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[4] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
        except:
            pass

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * sin(b * x_in + c)) + (d * sin(f * y_in + g));\n"
        return s



class SineB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Sine B [radians]"
    _HTML = "z = (a * sin(x)) * (b * sin(y))"
    coefficientDesignatorTuple = ('a', 'b')
    function_cpp_code = 'temp = (coeff[0] * _id[_cwo[0]+i]) * (coeff[1] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_SinX(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_SinY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * sin(x_in)) * (b * sin(y_in));\n"
        return s



class SineB_Transform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Sine B [radians] Transform"
    _HTML = "z = (a * sin(bx+c)) * (d * sin(fy+g))"
    coefficientDesignatorTuple = ('a', 'b', 'c', 'd', 'f', 'g')
    function_cpp_code = 'temp = (coeff[0] * sin(coeff[1] * _id[_cwo[0]+i] * coeff[2])) + (coeff[3] * sin(coeff[4] * _id[_cwo[1]+i] + coeff[5]));'


    def Initialize(self):
        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        try:
            nobs = len(self.IndependentDataArray[0])

            maxVal = max(self.IndependentDataArray[0])
            minVal = min(self.IndependentDataArray[0])
            self.upperCoefficientBoundsArray[1] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[1] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            
            maxVal = max(self.IndependentDataArray[1])
            minVal = min(self.IndependentDataArray[1])
            self.upperCoefficientBoundsArray[4] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[4] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
        except:
            pass

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * sin(b * x_in + c)) * (d * sin(f * y_in + g));\n"
        return s



class CoshA3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Cosh A [radians]"
    _HTML = "z = (a * cosh(x)) + (b * cosh(y))"
    coefficientDesignatorTuple = ('a', 'b')
    LinearSSQSolverFlag = 1
    function_cpp_code = 'temp = (coeff[0] * _id[_cwo[0]+i]) + (coeff[1] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_CoshX(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_CoshY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * cosh(x_in)) + (b * cosh(y_in));\n"
        return s



class CoshA_Transform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Cosh A [radians] Transform"
    _HTML = "z = (a * cosh(bx+c)) + (d * cosh(fy+g))"
    coefficientDesignatorTuple = ('a', 'b', 'c', 'd', 'f', 'g')
    function_cpp_code = 'temp = (coeff[0] * cosh(coeff[1] * _id[_cwo[0]+i] + coeff[2])) + (coeff[3] * cosh(coeff[4] * _id[_cwo[1]+i] + coeff[5]));'


    def Initialize(self):
        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        try:
            nobs = len(self.IndependentDataArray[0])

            maxVal = max(self.IndependentDataArray[0])
            minVal = min(self.IndependentDataArray[0])
            self.upperCoefficientBoundsArray[1] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[1] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            
            maxVal = max(self.IndependentDataArray[1])
            minVal = min(self.IndependentDataArray[1])
            self.upperCoefficientBoundsArray[4] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[4] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
        except:
            pass

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * cosh(b * x_in + c)) + (d * cosh(f * y_in + g));\n"
        return s



class CoshB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Cosh B [radians]"
    _HTML = "z = (a * cosh(x)) * (b * cosh(y))"
    coefficientDesignatorTuple = ('a', 'b')
    function_cpp_code = 'temp = (coeff[0] * _id[_cwo[0]+i]) * (coeff[1] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_CoshX(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_CoshY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * cosh(x_in)) * (b * cosh(y_in));\n"
        return s



class CoshB_Transform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Cosh B [radians] Transform"
    _HTML = "z = (a * cosh(bx+c)) * (d * cosh(fy+g))"
    coefficientDesignatorTuple = ('a', 'b', 'c', 'd', 'f', 'g')
    function_cpp_code = 'temp = (coeff[0] * cosh(coeff[1] * _id[_cwo[0]+i] * coeff[2])) + (coeff[3] * cosh(coeff[4] * _id[_cwo[1]+i] + coeff[5]));'


    def Initialize(self):
        pythonequations.EquationBaseClasses.Equation3D.Initialize(self)

        try:
            nobs = len(self.IndependentDataArray[0])

            maxVal = max(self.IndependentDataArray[0])
            minVal = min(self.IndependentDataArray[0])
            self.upperCoefficientBoundsArray[1] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[1] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            
            maxVal = max(self.IndependentDataArray[1])
            minVal = min(self.IndependentDataArray[1])
            self.upperCoefficientBoundsArray[4] = (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
            self.lowerCoefficientBoundsArray[4] = -1.0 * (maxVal - minVal) / nobs * 6.3 * 2.0 # the "* 2.0" is to allow slack
        except:
            pass

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * cosh(b * x_in + c)) * (d * cosh(f * y_in + g));\n"
        return s



class TanA3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Tan A [radians]"
    _HTML = "z = (a * tan(x)) + (b * tan(y))"
    coefficientDesignatorTuple = ('a', 'b')
    LinearSSQSolverFlag = 1
    function_cpp_code = 'temp = (coeff[0] * _id[_cwo[0]+i]) + (coeff[1] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_TanX(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_TanY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * tan(x_in)) + (b * tan(y_in));\n"
        return s



class TanATransform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Tan A [radians] Transform"
    _HTML = "z = (a * tan(bx + c)) + (d * tan(fy + g))"
    coefficientDesignatorTuple = ('a', 'b', 'c', 'd', 'f', 'g')
    function_cpp_code = 'temp = (coeff[0] * tan(coeff[1] * _id[_cwo[0]+i] * coeff[2])) + (coeff[3] * tan(coeff[4] * _id[_cwo[1]+i] + coeff[5]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * tan(b * x_in + c)) + (d * tan(f * y_in + g));\n"
        return s



class TanB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Tan B [radians]"
    _HTML = "z = (a * tan(x)) * (b * tan(y))"
    coefficientDesignatorTuple = ('a', 'b')
    function_cpp_code = 'temp = (coeff[0] * _id[_cwo[0]+i]) * (coeff[1] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_TanX(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_TanY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * tan(x_in)) * (b * tan(y_in));\n"
        return s



class TanBTransform3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name ="Tan B [radians] Transform"
    _HTML = "z = (a * tan(bx + c)) * (d * tan(fy + g))"
    coefficientDesignatorTuple = ('a', 'b', 'c', 'd', 'f', 'g')
    function_cpp_code = 'temp = (coeff[0] * tan(coeff[1] * _id[_cwo[0]+i] * coeff[2])) * (coeff[3] * tan(coeff[4] * _id[_cwo[1]+i] + coeff[5]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = (a * tan(b * x_in + c)) * (d * tan(f * y_in + g));\n"
        return s
